package io.afu.baseframework.components;


import ch.qos.logback.core.spi.LogbackLock;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import io.afu.baseframework.exceptions.BaseException;
import io.afu.baseframework.utils.CommonUtils;
import io.afu.baseframework.utils.TimeUtils;
import org.apache.catalina.connector.ResponseFacade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Component
public class AsyncLogger {


    private Logger logger = LoggerFactory.getLogger(getClass());

    private ObjectMapper objectMapper = setupObjectMapper();


    private ObjectMapper setupObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        return objectMapper;
    }

    @Async
    public void businessLog(final String className,final String methodName,final Object[] params,final Object result){
        try {
            StringBuilder sb2 = new StringBuilder();
            StringBuilder sbInput = new StringBuilder();
            sbInput.append("[");
            if (params != null){
                for (Object o:params){
                    logger.info(o.getClass().toString());
                    if (o instanceof MultipartFile) {
                        Map<String,String> map = new HashMap<>();
                        MultipartFile file = (MultipartFile) o;
                        map.put("filename",file.getOriginalFilename());
                        sbInput.append(objectMapper.writeValueAsString(map));
                    }else if (o instanceof BaseException){
                        BaseException msgCenterException = (BaseException) o;
                        sbInput.append("[FLAG:").append(msgCenterException.getCode());
                        sbInput.append("MSG:").append(msgCenterException.getMessage()).append("]");
                    }else if (o instanceof Exception){
                        Exception exception = (Exception) o;
                        sbInput.append("[MSG:").append(exception.getMessage()).append("]");
                    }else if (o instanceof HttpServletRequest){
                        HttpServletRequest request = (HttpServletRequest) o;
                        sbInput.append("[REQUEST_URL]:[").append(request.getRequestURI()).append("]").append(",");
                    }else if (o instanceof LogbackLock){
                        sbInput.append("[]").append(",");
                    }
                    else if (o instanceof ResponseFacade){
                        sbInput.append("[]").append(",");
                    }
                    else {
                        sbInput.append(objectMapper.writeValueAsString(o)).append(",");
                    }
                }
            }
            sbInput.append("]");
            sb2.append("\r\nAsyncLogger:********************************start\r\n")
                    .append("唯一代码:[").append(CommonUtils.getOrderNo()).append("]").append("]\r\n")
                    .append("执行时间:[").append(TimeUtils.getNow()).append("]\r\n")

                    .append("执行方法:[").append(className).append(".").append(methodName).append("]\r\n")
                    .append("输入参数:[").append(sbInput.toString()).append("]\r\n");
            String resultStr = "";
            if (result != null){
                if (result instanceof ResponseFacade){

                }else {
                    resultStr = JSON.toJSONString(result);
                }
            }

            sb2.append("返回参数:[").append(resultStr).append("]\r\n")
                    .append("AsyncLogger:********************************end\r\n");
            logger.info(sb2.toString());
        }catch (Exception e) {
            logger.error("打印日志出错",e);
        }

    }

    @Async
    public void businessLog(final String uniqueCode,final String className,final String methodName,final Object[] params){
        try {
            StringBuilder sb2 = new StringBuilder();
            StringBuilder sbInput = new StringBuilder();
            sbInput.append("[");
            if (params != null){
                for (Object o:params){
                    if (o instanceof MultipartFile) {
                        Map<String,String> map = new HashMap<>();
                        MultipartFile file = (MultipartFile) o;
                        map.put("filename",file.getOriginalFilename());
                        sbInput.append(objectMapper.writeValueAsString(map));
                    }else if (o instanceof BaseException){
                        BaseException msgCenterException = (BaseException) o;
                        sbInput.append("[FLAG:").append(msgCenterException.getCode());
                        sbInput.append("MSG:").append(msgCenterException.getMessage()).append("]");
                    }else if (o instanceof Exception){
                        Exception exception = (Exception) o;
                        sbInput.append("[MSG:").append(exception.getMessage()).append("]");
                    }else if (o instanceof HttpServletRequest){
                        HttpServletRequest request = (HttpServletRequest) o;
                        sbInput.append("[REQUEST_URL]:[").append(request.getRequestURI()).append("]").append(",");
                    }else if (o instanceof LogbackLock){
                        sbInput.append("[]").append(",");
                    }
                    else if (o instanceof ResponseFacade){
                        sbInput.append("[]").append(",");
                    }
                    else {
                        sbInput.append(objectMapper.writeValueAsString(o)).append(",");
                    }
                }
            }
            sbInput.append("]");
            sb2.append("\r\nAsyncLogger:********************************start\r\n")
                    .append("唯一代码:[").append(uniqueCode).append("]").append("]\r\n")
                    .append("执行时间:[").append(TimeUtils.getNow()).append("]\r\n")
                    .append("执行方法:[").append(className).append(".").append(methodName).append("]\r\n")
                    .append("输入参数:[").append(sbInput.toString()).append("]\r\n")
                    .append("AsyncLogger:********************************end\r\n");
            logger.info(sb2.toString());
        }catch (Exception e) {
            logger.error("打印日志出错",e);
        }
    }

    @Async
    public void budinessLog(final String uniqueCode,final Object result) {
        try {
            String outStr = null == result?"":objectMapper.writeValueAsString(result);
            logger.info("唯一代码:["+uniqueCode+"],方法返回结果为:["+outStr+"]");
        }catch (Exception e){
            logger.error("打印日志出错了",e);
        }

    }


}
